using Microsoft.EntityFrameworkCore;
using TerritoryGame.Application.Commands;
using TerritoryGame.Application.Handlers.CommandHandlers;
using TerritoryGame.Application.Queries;
using TerritoryGame.Domain.Repositories;
using TerritoryGame.Infrastructure.Persistence;
using TerritoryGame.Infrastructure.Persistence.Repositories;
using TerritoryGame.API.Hubs;
using TerritoryGame.API.Middleware;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
    {
        Title = "涂色抢地盘游戏 API",
        Version = "v1",
        Description = "多人实时涂色竞技游戏的API文档",
        Contact = new Microsoft.OpenApi.Models.OpenApiContact
        {
            Name = "开发团队",
            Email = "dev@territorygame.com"
        }
    });
});

// Add SignalR
builder.Services.AddSignalR();

// Add MediatR
builder.Services.AddMediatR(cfg => {
    cfg.RegisterServicesFromAssembly(typeof(CreateRoomCommand).Assembly);
});

// Add Entity Framework
builder.Services.AddDbContext<GameDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"), 
        b => b.MigrationsAssembly("TerritoryGame.Infrastructure")));

// Add Redis
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
});

// Add Repositories
builder.Services.AddScoped<IGameRepository, GameRepository>();
builder.Services.AddScoped<IGameRoomRepository, GameRoomRepository>();

// Add CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.WithOrigins("http://localhost:3000", "http://localhost:3001", "http://localhost:5173")
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowCredentials();
    });
});

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
    {
        policy.WithOrigins("http://localhost:3001")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

var app = builder.Build();


app.UseCors("AllowFrontend");

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseCors("AllowAll");
app.UseAuthorization();

// 添加全局异常处理中间件
app.UseMiddleware<ExceptionHandlingMiddleware>();

app.MapControllers();
app.MapHub<GameHub>("/gamehub");

// 数据库初始化（智能控制）
using (var scope = app.Services.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<GameDbContext>();
    try
    {
        // 检查是否需要强制迁移（通过环境变量控制）
        var forceMigration = Environment.GetEnvironmentVariable("FORCE_MIGRATION") == "true";
        var forceSeed = Environment.GetEnvironmentVariable("FORCE_SEED") == "true";
        
        if (forceMigration)
        {
            Console.WriteLine("🔄 强制迁移模式：正在应用数据库迁移...");
            context.Database.Migrate();
            Console.WriteLine("✅ 数据库迁移完成");
        }
        
        // 检查数据库连接
        if (!context.Database.CanConnect())
        {
            Console.WriteLine("🔄 数据库不存在，正在创建并应用迁移...");
            context.Database.Migrate();
            
            // 仅在数据库首次创建时或强制种子模式下添加种子数据
            if (forceSeed || !context.GameRooms.Any())
            {
                SeedData.Seed(context);
                Console.WriteLine("✅ 数据库创建完成，种子数据已添加");
            }
        }
        else if (forceSeed)
        {
            Console.WriteLine("🔄 强制种子模式：正在添加种子数据...");
            SeedData.Seed(context);
            Console.WriteLine("✅ 种子数据已添加");
        }
        else
        {
            Console.WriteLine("✅ 数据库连接正常，跳过迁移和种子数据");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"❌ 数据库初始化失败: {ex.Message}");
    }
}

app.Run();
